#ifndef _FS_H
#define _FS_H

#ifdef __cplusplus
extern "C" {
#endif

#include <types.h>

#define FS_FILE        0x01
#define FS_DIRECTORY   0x02
#define FS_CHARDEVICE  0x03
#define FS_BLOCKDEVICE 0x04
#define FS_PIPE        0x05
#define FS_SYMLINK     0x06
#define FS_MOUNTPOINT  0x08		// Файл является активной точкой монтирования?

struct fs_node;

// Первые четыре можно получить, просматривая спецификации POSIX
typedef uint32 (*read_type_t)(struct fs_node*,uint32,uint32,uint8*);
typedef uint32 (*write_type_t)(struct fs_node*,uint32,uint32,uint8*);
typedef void (*open_type_t)(struct fs_node*);
typedef void (*close_type_t)(struct fs_node*);
typedef struct dirent * (*readdir_type_t)(struct fs_node*,uint32);
typedef struct fs_node * (*finddir_type_t)(struct fs_node*,char *name);

typedef struct fs_node
{
    char name[128];				// Имя файла.
    uint32 mask;				// Маска прав доступа.
    uint32 uid;					// Пользователь, владеющий файлом.
    uint32 gid;					// Группа, владеющая файлом.
    uint32 flags;				// Включает тип нода.
    uint32 inode;				// Зависит от устройства, позволяет файловой системе идентифицировать файлы.
    uint32 length;				// Размер файла в байтах.
    uint32 impl;				// Номер,б зависящий от реализации.
    read_type_t read;
    write_type_t write;
    open_type_t open;
    close_type_t close;
    readdir_type_t readdir;
    finddir_type_t finddir;
    struct fs_node *ptr;		// Используется для точек монтирования и символических ссылок.
} fs_node_t;

struct dirent					// One of these is returned by the readdir call, according to POSIX.
{
    char name[128];				// Имя файла..
    uint32 ino;					// Номер inode. Требуеся для POSIX.
};

extern fs_node_t *fs_root;		// The root of the filesystem.

// Стандартные функции чтения, записи, открытия, закрытия. Обратите внимание,
// что у них всех используется суффикс _fs с тем, чтобы отличать от функций чтения, 
// записи, открытия и закрытия дескрипторов файлов, а не нодов файлов. 
uint32 read_fs(fs_node_t *node, uint32 offset, uint32 size, uint8 *buffer);
uint32 write_fs(fs_node_t *node, uint32 offset, uint32 size, uint8 *buffer);
void open_fs(fs_node_t *node, uint8 read, uint8 write);
void close_fs(fs_node_t *node);
struct dirent *readdir_fs(fs_node_t *node, uint32 index);
fs_node_t *finddir_fs(fs_node_t *node, char *name);

#ifdef __cplusplus
}
#endif

#endif
